﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ModulesInfrastructure.ViewModels;
using Microsoft.Practices.Prism.Events;
using ServerConnection;
using System.Windows.Input;
using ModuleAddPlace.Commands;
using System.ComponentModel;
using System.Collections.ObjectModel;
using ServerConnection.ShopServiceReference;
using EventInfrastructure;

namespace ModuleAddPlace.ViewModels
{  
    public class AddPlaceViewModel : SharedViewModel, IAddPlaceViewModel, INotifyPropertyChanged
    {
        #region Private members

        /// <summary>
        /// list of address-languages pairs
        /// </summary>
        private List<PlaceLocalizationModel> m_localizations = new List<PlaceLocalizationModel>();

        /// <summary>
        /// entered address on a specific language. currentAddress = "Dnipro", language = "eng"
        /// </summary>
        private string m_currentAddress = string.Empty;

        /// <summary>
        /// entered Place name
        /// </summary>
        private string currentPlaceName = string.Empty;

        private IEventAggregator m_eventAggregator;

        /// <summary>
        /// When click on Save button
        /// </summary>
        private SavePlaceCommand m_SavePlaceCommand;

        /// <summary>
        /// When click on Add address button
        /// </summary>
        private AddAddressCommand m_AddAddressCommand;

        /// <summary>
        /// Selected language in combobox
        /// </summary>
        private KeyValuePair<string, string> selectedLanguage;

        /// <summary>
        /// List of current user's languages for displaying in combobox. 
        /// List is a copy of list, which is in Service.GetLanguages()
        /// because we need to remove some elements, when add a new address, and disable them from being watched
        /// </summary>
        private Dictionary<string, string> m_languagesToDisplay;
        

        /// <summary>
        /// Update property for updating the combobox, binded to it: languages of current user
        /// </summary>
        private void m_UpdateLanguagesOfCurrentUser()
        {
            Languages = m_languagesToDisplay;         
        }

        /// <summary>
        /// This method is called up when the property is changed
        /// </summary>
        /// <param name="propertyName"></param>
        private void m_OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                //fire event
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion Private members        


        #region Public properties
      
        /// <summary>
        /// List of languages of current user. Binded to combobox
        /// </summary>
        public IEnumerable<KeyValuePair<string, string>> Languages
        {
            get
            {
                //return m_languagesToDisplay;
                foreach (KeyValuePair<string, string> elem in m_languagesToDisplay)
                    yield return elem;  
            }
            set
            {
                m_languagesToDisplay = (Dictionary<string, string>) value;
                m_OnPropertyChanged("Languages"); //for updating ui                    
            }
        }

        /// <summary>
        /// For ListBox of added localizations
        /// </summary>
        public IEnumerable<PlaceLocalizationModel> Localizations
        {
            get
            {
                foreach (PlaceLocalizationModel elem in m_localizations)
                    yield return elem;  
            }
            set
            {
                m_localizations = (List<PlaceLocalizationModel>)value;
                m_OnPropertyChanged("Localizations");
            }
        }

        /// <summary>
        /// Command AddAddressCommand.For binding to ui
        /// </summary>
        public AddAddressCommand AddAddressCommand
        {
            get { return m_AddAddressCommand; }
        }

        /// <summary>
        /// Command SavePlaceCommand.For binding to ui
        /// </summary>
        public SavePlaceCommand SavePlaceCommand
        {
            get { return m_SavePlaceCommand; }
        }

        /// <summary>
        /// Selected language in combobox
        /// </summary>
        public KeyValuePair<string, string> OnSelectedLanguage
        {
            get { return selectedLanguage; }
            set
            {
                selectedLanguage = value;
                m_OnPropertyChanged("OnSelectedLanguage"); //for ui
            }
        }

        /// <summary>
        ///  entered address on a specific language. currentAddress = "Dnipro", language = "eng"
        ///  Binds to textbox
        /// </summary>
        public string CurrentAddress
        {
            get
            {
                return m_currentAddress;
            }
            set
            {
                m_currentAddress = value;
                m_OnPropertyChanged("CurrentAddress");
            }
        }

        /// <summary>
        ///  entered place name
        ///  Binds to textbox
        /// </summary>
        public string CurrentPlace
        {
            get
            {
                return currentPlaceName;
            }
            set
            {
                currentPlaceName = value;
                m_OnPropertyChanged("CurrentPlace");
            }
        }        

        #endregion Public properties


        #region Public methods

        /// <summary>
        /// Constructor
        /// </summary>       
        public AddPlaceViewModel(IEventAggregator eventAggregator)
        {
            ///Get languages of current user for the 1st time
            m_languagesToDisplay = Service.GetLanguages();

            ///Create command, add viewmodel to constructor
            m_AddAddressCommand = new AddAddressCommand(this);

            ///Create command   
            m_SavePlaceCommand = new SavePlaceCommand(this);

            ///Set the eventAggregator
            this.m_eventAggregator = eventAggregator;

            ///Show languages of current user in combobox
            m_UpdateLanguagesOfCurrentUser();
        }

        /// <summary>
        /// Remove one address from dictionary and from combobox
        /// </summary>
        public void RemoveAddedAddress()
        {
            PlaceLocalizationModel localization = new PlaceLocalizationModel();

            ///set chosen language from combobox
            localization.Language = selectedLanguage.Key;
            ///set entered address
            localization.Address = m_currentAddress;
            ///Add localization to list
            m_localizations.Add(localization);
            ///Update the ui
            Localizations = m_localizations;

            ///Remove selected language from combobox
            m_languagesToDisplay.Remove(selectedLanguage.Key);

            ///clear current address. clear textbox
            CurrentAddress = string.Empty;

            ///Update language list
            m_UpdateLanguagesOfCurrentUser();

            RaisePropertyChanged(() => this.Languages);
        }

        /// <summary>
        /// Save new place
        /// </summary>
        public void SaveNewPlace()
        {
            PlaceAll newPlace = new PlaceAll();

            ///0 means adding new 
            newPlace.Id = 0;
            newPlace.Localizations = m_localizations.ToArray();
            newPlace.Name = currentPlaceName;

            ///Add new place
            ServerConnection.Service.Instance.AddPlace(newPlace);
            
            ///clear entered place
            CurrentPlace = string.Empty;

            ///Clear localization list
            m_localizations.Clear();
            ///Update the ui (Clear)
            Localizations = m_localizations;

            ///Update places ListBox in the Left region
            ///1 - not used
            m_eventAggregator.GetEvent<AddOrUpdatePlaceEvent>().Publish(1);

            ///Get Update list of languages for current user
            m_languagesToDisplay = Service.GetLanguages();
            ///update the ui
            Languages = m_languagesToDisplay;
        }

        #endregion Public methods


        #region Events

        /// <summary>
        /// PropertyChanged is needed for binding to ui
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion Events

    }//class
}
